#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/gpio.h>
#include <linux/interrupt.h>
#include <linux/of_gpio.h>
#include <linux/of_irq.h>
#include <linux/cdev.h>
#include <linux/wait.h>
#include <linux/sched.h>
#include <linux/poll.h>
#include <linux/mm.h>
#include <linux/input.h>
#include <linux/delay.h>
#include <linux/slab.h>
#include <asm/uaccess.h>


struct fs4412key2_dev
{
	struct input_dev *pdev;
	
	int gpio;
	int irqno;
};

struct fs4412key2_dev *pgmydev = NULL;

irqreturn_t key2_irq_handle(int no,void *arg)
{
	struct fs4412key2_dev *pmydev = (struct fs4412key2_dev *)arg;
	int status1 = 0;
	int status2 = 0;

	status1 = gpio_get_value(pmydev->gpio);
	mdelay(1);
	status2 = gpio_get_value(pmydev->gpio);

	if(status1 != status2)
	{
		return IRQ_NONE;
	}

	if(status1)
	{
		//上报事件
		input_event(pmydev->pdev,EV_KEY,KEY_2,0);
		//上报完成后需要调用这些函数来通知系统处理完整事件
		input_sync(pmydev->pdev);
	}
	else
	{
		//上报事件
		input_event(pmydev->pdev,EV_KEY,KEY_2,1);
		//上报完成后需要调用这些函数来通知系统处理完整事件
		input_sync(pmydev->pdev);
	}

	return IRQ_HANDLED;
}

int __init fs4412key2_init(void)
{
	int ret = 0;

	struct device_node *pnode = NULL;

	pnode = of_find_node_by_path("/mykey2_node");
	if(NULL == pnode)
	{
		printk("find node failed\n");
		return -1;
	}


	pgmydev = (struct fs4412key2_dev *)kmalloc(sizeof(struct fs4412key2_dev),GFP_KERNEL);
	if(NULL == pgmydev)
	{
		printk("kmallc for struct fs4412key2_dev failed\n");
		return -1;
	}

	pgmydev->gpio = of_get_named_gpio(pnode,"key2-gpio",0);

	pgmydev->irqno = irq_of_parse_and_map(pnode,0);

	pgmydev->pdev = input_allocate_device();
	
	//支持的事件类型（如 EV_KEY、EV_REL、EV_ABS）
	set_bit(EV_KEY,pgmydev->pdev->evbit);
	
	//支持的按键/键盘事件（如 KEY_A、BTN_LEFT）
	set_bit(KEY_2,pgmydev->pdev->keybit);

	ret = input_register_device(pgmydev->pdev);
	
	ret = request_irq(pgmydev->irqno,key2_irq_handle,IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,"fs4412key2",pgmydev);
	if(ret)
	{
		printk("request_irq failed\n");
		input_unregister_device(pgmydev->pdev);
		input_free_device(pgmydev->pdev);
		kfree(pgmydev);
		pgmydev = NULL;
		return -1;
	}
	return 0;
}

void __exit fs4412key2_exit(void)
{

	free_irq(pgmydev->irqno,pgmydev);

	input_unregister_device(pgmydev->pdev);
	input_free_device(pgmydev->pdev);

	kfree(pgmydev);
	pgmydev = NULL;
}


MODULE_LICENSE("GPL");

module_init(fs4412key2_init);
module_exit(fs4412key2_exit);
